<template>
  <article class="page page-watermark-remove-ffmpeg">
    <h4 class="text-center">视频&图片去水印(FFmpeg)</h4>
    <form class="form">
      <div class="form-group">
        <fieldset>
          <legend>参数设置</legend>
          <div class="alert alert-info">
            本工具基于ffmpeg，需要先行安装ffmpeg，并加入到环境变量。
          </div>
          <div class="row">
            <div class="col col-3">
              <div class="input-group mb-3">
                <div class="input-group-prepend"><span class="input-group-text">水印坐标X</span></div>
                <input type="number" :min="1" class="form-control" v-model="watermarkX">
              </div>
            </div>
            <div class="col col-3">
              <div class="input-group mb-3">
                <div class="input-group-prepend"><span class="input-group-text">水印坐标Y</span></div>
                <input type="number" :min="1" class="form-control" v-model="watermarkY">
              </div>
            </div>
            <div class="col col-3">
              <div class="input-group mb-3">
                <div class="input-group-prepend"><span class="input-group-text">水印宽度</span></div>
                <input type="number" :min="1" class="form-control" v-model="watermarkW">
              </div>
            </div>
            <div class="col col-3">
              <div class="input-group mb-3">
                <div class="input-group-prepend"><span class="input-group-text">水印高度</span></div>
                <input type="number" :min="1" class="form-control" v-model="watermarkH">
              </div>
            </div>
          </div>
        </fieldset>
      </div>
      <div class="form-group form-group-main row">
        <div class="col col-6">
            <fieldset>
                <legend>文件列表</legend>
                <div class="fieldset-content">
                    <div class="pending-list" @drop.prevent="drop" @dragover.prevent >
                        <div class="pending-item" v-for="(v,i) in filesList" :key="`pending_${i}`"
                          :class="{active: i === fileActiveIndex}"
                          @click.stop="clickFileItem(i)"
                        >
                            <div class="pending-item-text text-ellipsis" :title="v.path">{{v.name}}</div>
                            <div class="pending-item-status">{{fileStatusList[v.status]}}</div>
                            <div class="pending-item-btns">
                                <template v-if="v.status === 0 || v.status === 3">
                                    <button type="button" class="btn btn-link btn-sm" @click.stop="removeWatermarkItem(i)">去水印</button>
                                    <button type="button" class="btn btn-link btn-sm" @click.stop="fileItemDelete(i)">删除</button>
                                </template>
                                <template v-else-if="v.status === 1">
                                    <div class="pending-item-btn"><x-loading></x-loading></div>
                                </template>
                                <template v-else-if="v.status === 2">
                                    <button type="button" class="btn btn-link btn-sm" @click.stop="fileItemDelete(i)">删除</button>
                                </template>
                            </div>
                        </div>
                        <div v-if="filesList.length===0" class="nodata">将待处理的文件拖动到此处</div>
                    </div>
                </div>
            </fieldset>
        </div>
        <div class="col col-6">
            <fieldset>
                <legend>文件预览</legend>
                <div class="fieldset-content preview">
                    <!-- <video v-if="filePreviewInfo.type==='video'" class="preview-video" :src="filePreviewInfo.src1 || filePreviewInfo.src || ''" controls></video>
                    <img v-else class="preview-img" :src="filePreviewInfo.src1 || filePreviewInfo.src || ''" /> -->
                    <webview class="preview-webview" :src="filePreviewInfo.src1 || ''"></webview>
                    <!-- <div class="preview-name text-ellipsis">{{filePreviewInfo.name}}</div> -->
                </div>
            </fieldset>
        </div>
      </div>
      <div class="form-group text-center">
        <x-button type="default" @click="clearFilesList">清空列表</x-button>
        <x-button type="primary" @click="removeWatermarkAll">去除水印</x-button>
      </div>
    </form>
  </article>
</template>

<script>
const fs = global.require('fs')
const path = global.require('path')
const {exec} = global.require('child_process')

export default {
  name: 'watermark-remove-ffmpeg',
  data () {
    return {
      watermarkX: 1,
      watermarkY: 1,
      watermarkW: 50,
      watermarkH: 50,
      filesList: [],
      fileActiveIndex: -1,
      fileStatusList: ['未处理', '正在处理', '已处理', '处理失败']
    }
  },
  computed: {
    filePreviewInfo () {
      return this.filesList[this.fileActiveIndex] || {}
    }
  },
  methods: {
    // 拖拽添加文件
    drop (e) {
      const fileList = e.dataTransfer.files
      if (!fileList) return
      let taskList = []
      let indexList = []
      for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i]
        if (!file.type || !/.(flv|mp4|rmvb|avi|mpeg|ra|ram|mov|wmv|gif|jpg|jpeg|png)$/i.test(file.name)) {
          continue
        }
        taskList.push(this.$jstools.File2dataUrl(file))
        indexList.push(i)
      }
      Promise.all(taskList).then((urls) => {
        urls.forEach((v, i) => {
          let file = fileList[indexList[i]]
          let fileType = 'image'
          if (/.(flv|mp4|rmvb|avi|mpeg|ra|ram|mov|wmv)$/i.test(file.name)) { fileType = 'video' }
          this.filesList.push({
            name: file.name, type: fileType, src: v, src1: new URL(file.path).href, path: file.path, ext: path.extname(file.path), status: 0
          })
        })
      })
    },
    // 点击文件
    clickFileItem (index) {
      if (this.fileActiveIndex === index) {
        this.fileActiveIndex = -1
      } else {
        this.fileActiveIndex = index
      }
    },
    // 删除文件
    fileItemDelete (index) {
      this.filesList.splice(index, 1)
      if (this.fileActiveIndex === index) {
        this.fileActiveIndex = -1
      } else if (this.fileActiveIndex > index) {
        this.fileActiveIndex -= 1
      }
    },
    // 清空列表
    clearFilesList () {
      this.filesList = []
      this.fileActiveIndex = -1
    },
    // 去除水印
    removeWatermarkAll () {
      if (this.filesList.length <= 0) {
        this.$toast('未找到可处理的文件')
        return
      }
      let taskList = []
      this.filesList.forEach((v, i) => {
        taskList.push(this.removeWatermarkItem(i))
      })
      Promise.all(taskList).finally(() => {
        this.$toast('文件处理完成')
      })
    },
    removeWatermarkItem (index) {
      return new Promise((resolve, reject) => {
        let item = this.filesList[index]
        if (item.status !== 0 && item.status !== 3) return reject('文件已处理或正在处理')
        item.status = 1
        this.$nextTick(() => {
          let fromFilePath = item.path
          let toFilePath = (item.path.substring(0, item.path.length - item.ext.length) + `_nowater${item.ext}`)
          let i = 1
          while (fs.existsSync(toFilePath)) {
            toFilePath = (item.path.substring(0, item.path.length - item.ext.length) + `_nowater_${i}${item.ext}`)
            i++
          }
          let command = `ffmpeg.exe -i "${fromFilePath}" -strict -2 -vf delogo=x=${this.watermarkX}:y=${this.watermarkY}:w=${this.watermarkW}:h=${this.watermarkH}:show=0 "${toFilePath}"`
          if (item.type === 'video') {
            command = `ffmpeg.exe -i "${fromFilePath}" -filter_complex "[0:v]delogo=x=${this.watermarkX}:y=${this.watermarkY}:w=${this.watermarkW}:h=${this.watermarkH}" -c:a copy "${toFilePath}"`
          }
          exec(command, (error, stdout, stderr) => {
            if (error) {
              this.filesList[index].status = 3
              reject(error)
            } else {
              this.filesList[index].src1 = new URL(toFilePath).href
              this.filesList[index].status = 2
              resolve()
            }
            console.error(`stderr: ${stderr}`)
            console.info(`stdout: ${stdout}`)
          })
        })
      })
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.row-flex {
  & + .row-flex { margin-top: .5em; }
  .row-flex-prefix { width: 4.5em; text-align: left; }
}
.form {
  height: calc(100vh - 137px);
  display: flex;
  flex-direction: column;
  .form-group {
    fieldset {
        height: 100%;
        .fieldset-content {
            height: calc(100% - 2em);
            display: flex;
            flex-direction: column;
            .pending-list {
                height: 0;
                flex-grow: 1;
                padding: .5em;
                border-radius: .5em;
                background-color: #fff;
                box-shadow: 0 0 .5em @bgGrey;
                font-size: .9em;
                overflow: hidden auto;
                position: relative;
                .pending-item {
                    height: 2em;
                    padding-left: .5em;
                    padding-right: .5em;
                    display: flex;
                    align-items: center;
                    border-bottom: 1px dashed @borderGrey;
                    cursor: pointer;
                    &.active {
                      background-color: fade(@bgGrey, 50);
                    }
                    .pending-item-text { width: 0; flex-grow: 1; }
                    .pending-item-status { width: 8em; text-align: center; }
                    .pending-item-btns { width: 8em; text-align: center; }
                    .pending-item-btn { padding: 0 .5em; cursor: pointer; }
                }
            }
            .preview-video,
            .preview-img {
              display: block;
              width: 100%;
              height: 100%;
              max-width: 100%;
              max-height: 100%;
              object-fit: contain;
            }
            .preview-iframe {
              display: block;
              width: 100%;
              height: 100%;
            }
            .preview-webview {
              width: 100%;
              height: 100%;
            }
            .preview-name {
              position: absolute;
              bottom: 0;
              left: 0;
              width: 100%;
              height: 2em;
              line-height: 2;
              color: #fff;
              text-align: center;
              background-color: rgba(0, 0, 0, .3);
            }
        }
        .preview {
          border-radius: .5em;
          background-color: @bgGrey;
          overflow: hidden;
          position: relative;
        }
    }
  }
  .form-group-main {
    height: 0;
    flex-grow: 1;
    & > .col {height: 100%;}
  }
  .alert-info { margin-bottom: 1em; }
}
</style>
